home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / xpipeman / game.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  18.7 KB  |  761 lines

  1. /*
  2.  * game.c  - Xpipeman
  3.  *
  4.  * Send Constructive comments, bug reports, etc. to either
  5.  *
  6.  *          JANET: pavern@uk.ac.man.cs
  7.  *
  8.  *  or      INER : pavern%cs.man.ac.uk@nsfnet-relay.ac.uk
  9.  *
  10.  * All other comments > /dev/null !!
  11.  * 
  12.  * Copyright 1991 Nigel Paver
  13.  * 
  14.  * Permission to use, copy, modify, distribute, and sell this software and its
  15.  * documentation for any purpose is hereby granted without fee, provided that
  16.  * the above copyright notice appear in all copies and that both that
  17.  * copyright notice and this permission notice appear in supporting
  18.  * documentation, and that the author's name not be used in advertising or
  19.  * publicity pertaining to distribution of the software without specific,
  20.  * written prior permission.  The author makes no representations about the
  21.  * suitability of this software for any purpose.  It is provided "as is"
  22.  * without express or implied warranty.
  23.  * 
  24.  * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 
  25.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE 
  26.  * AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 
  27.  * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
  28.  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
  29.  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  30.  * 
  31.  *
  32.  *
  33.  * Acknowledgements to Brian Warkentine (brian@sun.COM) for his xrobots
  34.  * program (copyright  1989) which I cannibalized to write this program
  35.  */
  36.  
  37. #include <X11/Intrinsic.h>
  38. #include "xpipeman.h"
  39.  
  40. /* some of these are global */
  41. int block_x, block_y, last_block_x, last_block_y;
  42. int buttons_disabled;
  43. int remaining_blocks;
  44. int current_block; /*current block type*/
  45.  
  46.  
  47.  
  48. XtIntervalId current_callback;
  49.  
  50. int pipe_board[MAXX][MAXY];
  51.  
  52. int    score,
  53.         bonus,
  54.     level,
  55.     game_active;
  56.  
  57. static int last_new_block;
  58. static int num_blk[TOTALBLOCKS+1];  /*count number of type of each block*/
  59. static int blktime, blkrstart,blkfull,blkstarttime;
  60. static int flow_x,flow_y,flow_dir,flow_blocks,flow_time,flow_time_start;
  61.  
  62. #define FUP    0
  63. #define FDOWN  3
  64. #define FLEFT  1
  65. #define FRIGHT 2
  66.  
  67. #define BLOCKED 4 
  68.  
  69. /* Model of the flow through the various blocks */
  70.  
  71. static int flow[TOTALBLOCKS+2][5]=
  72.      { { BLOCKED,BLOCKED,BLOCKED,BLOCKED,BLOCKED}, /* EMPTY Block */
  73.      { BLOCKED,FRIGHT,FLEFT,BLOCKED,BLOCKED},   /*1*/
  74.      { FDOWN,BLOCKED,BLOCKED,FUP,BLOCKED},      /*2*/
  75.      { BLOCKED,BLOCKED,FDOWN,FRIGHT,BLOCKED},   /*3*/
  76.      { BLOCKED,FDOWN,BLOCKED,FLEFT,BLOCKED},    /*4*/
  77.      { FRIGHT,BLOCKED,FUP,BLOCKED,BLOCKED},     /*5*/
  78.      { FLEFT,FUP,BLOCKED,BLOCKED,BLOCKED},      /*6*/
  79.      { FDOWN,FRIGHT,FLEFT,FUP,BLOCKED},         /*7*/
  80.      { BLOCKED,FRIGHT,BLOCKED,BLOCKED,BLOCKED}, /*1 - 1way*/
  81.      { FDOWN,BLOCKED,BLOCKED,BLOCKED,BLOCKED},  /*2 - 1way*/
  82.      { BLOCKED,BLOCKED,BLOCKED,FRIGHT,BLOCKED}, /*3 - 1way*/
  83.      { BLOCKED,BLOCKED,BLOCKED,FLEFT,BLOCKED},  /*4 - 1way*/
  84.      { FRIGHT,BLOCKED,BLOCKED,BLOCKED,BLOCKED}, /*5 - 1way*/
  85.      { FLEFT,BLOCKED,BLOCKED,BLOCKED,BLOCKED},  /*6 - 1way*/
  86.      { FDOWN,BLOCKED,BLOCKED,FUP,BLOCKED},      /*8*/
  87.      { BLOCKED,FRIGHT,FLEFT,BLOCKED,BLOCKED},   /*9*/
  88.        };
  89.  
  90. #define MAXLEVELS 35
  91.  
  92. static int obmaps[MAXLEVELS][MAXY]=
  93. {{0,0,0,0,0,0,0,0,0,0}, /*0*/
  94.  {0,0,0,0,7,0,0,0,0,0},
  95.  {0,0,9,0,0,0,0,3,0,0},
  96.  {0,2,0,0,6,0,0,0,4,0},
  97.  {0,0,4,0,6,0,8,0,0,0},
  98.  {0,9,0,1,0,8,0,2,0,0}, /*5*/
  99.  {0,0,0,5,4,6,8,7,0,0},
  100.  {0,3,0,10,0,6,0,1,8,0},
  101.  {0,2,7,0,5,0,8,6,3,0},
  102.  {0,1,2,6,8,0,9,4,7,0},
  103.  {0,9,1,8,2,7,3,6,4,0}, /*10*/
  104.  {0,4,6,3,7,2,8,1,9,0},
  105.  {6,6,6,6,6,0,6,6,6,6},
  106.  {8,8,8,8,8,8,8,8,0,8},
  107.  {0,2,0,0,6,0,0,0,4,0},  /* level 14 repeat but with one way bits */
  108.  {0,0,4,0,6,0,8,0,0,0},
  109.  {0,9,0,1,0,8,0,2,0,0},
  110.  {0,0,0,5,4,6,8,7,0,0},
  111.  {0,3,0,10,0,6,0,1,8,0},
  112.  {0,2,7,0,5,0,8,6,3,0},
  113.  {0,1,2,6,8,0,9,4,7,0},  /*20*/
  114.  {0,9,1,8,2,7,3,6,4,0},
  115.  {0,4,6,3,7,2,8,1,9,0},
  116.  {6,6,6,6,6,0,6,6,6,6},
  117.  {8,8,8,8,8,8,8,8,0,8},  /* level 24 start to wind up the speed */
  118.  {2,9,3,8,4,7,5,6,6,5},
  119.  {0,1,2,6,8,0,9,4,7,0},
  120.  {0,9,1,8,2,7,3,6,4,0},
  121.  {0,4,6,3,7,2,8,1,9,0},
  122.  {4,4,4,0,4,4,4,0,4,4},  /*30 */
  123.  {0,6,6,6,6,6,6,6,6,0},
  124.  {5,5,5,5,0,5,5,5,5,0},
  125.  {6,6,6,6,6,0,6,6,6,6},
  126.  {3,3,3,3,3,3,3,3,3,0},
  127.  {2,9,3,8,4,7,5,6,6,5}  /*35 levels*/
  128. };
  129.  
  130.  
  131. /* Minimum number of connected blocks to complete each stage*/
  132. static int blocksrequired[MAXLEVELS]=
  133.     {4,5,6,7,8,9,10,11,12,13,14,15,20,25,       /* 0  -13 */
  134.      10,12,14,16,20,24,28,32,36,40,             /* 14 -23 */
  135.      35,36,37,38,40,41,42,43,44,45,50};         /* 24 -34*/
  136.  
  137. /*flow rates in mSecs*/
  138. static int flowrate[MAXLEVELS]=
  139.       {1000,1000,1000,1000,1000,980,970,950,920,900,850,825,800,775, /* 0 -13*/
  140.        1000,980,970,950,920,900,850,825,800,775,                     /*14 -23*/
  141.        775,725,700,650,600,550,500,500,475,450,400};             /*24- 34*/
  142.  
  143. static int flowstart[MAXLEVELS]={50000,50000,50000,50000,50000,  /* 0 -4 */
  144.                  45000,45000,45000,45000,45000,  /* 5 -9*/
  145.                  40000,40000,40000,40000,50000,  /* 10 -14*/
  146.                  48000,46000,44000,42000,40000,  /* 15 -19 */
  147.                  39000,38000,37000,36000,35000,  /* 20 -24 */
  148.                  32000,30000,28000,26000,24000,  /* 25 -29 */
  149.                  22000,20000,18000,16000,14000}; /* 30 -34 */
  150.  
  151. static int MaxBlockNo;  /*maxmimum block allowed in random sequence*/
  152.  
  153. static int onewaytime=14;  /*start oneway blocks on level 14*/
  154. static int oneway=1;   /* number of 1 way blocks in the sequence at present*/
  155. #define MAXONEWAYS 2   /* maximum one ways in the sequence at any one time*/
  156.  
  157. void start_new_level();
  158. void level_over();
  159. void game_over();
  160. void reset_score();
  161. void show_when_flow();
  162. /*----------------------------------------------------------------------*/
  163. void
  164. new_score(n)
  165.   int n;
  166. {
  167.   score += n;
  168.   update_score(score);
  169. }
  170. /*----------------------------------------------------------------------*/
  171. void
  172. new_bonus(n)
  173.   int n;
  174. {
  175.   bonus += n;
  176.   update_bonus(bonus);
  177. }
  178. /*----------------------------------------------------------------------*/
  179. void
  180. reset_score()
  181. {
  182.   score =0;
  183.   update_score(score);
  184. }
  185. /*----------------------------------------------------------------------*/
  186. void
  187. reset_bonus()
  188. {
  189.   bonus =0;
  190.   update_bonus(bonus);
  191. }
  192. /*----------------------------------------------------------------------*/
  193. void
  194. reset_level()
  195. {
  196.   level =0;
  197.   update_level(level);
  198. }
  199.  
  200. /*----------------------------------------------------------------------*/
  201. void
  202. new_game()
  203. {
  204.  buttons_disabled=1;
  205.  game_active= 1; 
  206.  reset_score();
  207.  reset_bonus();
  208.  reset_level();
  209.  all_popdown();
  210.  flow_blocks=0;
  211.  current_block = 0;
  212.  new_level();
  213.  
  214. }
  215. /*----------------------------------------------------------------------*/
  216. int
  217. place_block()
  218. {
  219.   if (can_place(block_x,block_y))
  220.       {
  221.     remove_block();    /* from *random* sequence stats */
  222.         if (pipe_board[block_x][block_y] != EMPTY)
  223.       new_score(-20);   /* changing blocks costs double points! */
  224.     pipe_board[block_x][block_y] = current_block;   
  225.     redraw_block(block_x,block_y);
  226.     increment_sequence();
  227.     reset_block_origin();
  228.     return 1;
  229.       }
  230.   else
  231.     return 0;
  232. }
  233. /*----------------------------------------------------------------------*/
  234. void
  235. reset_block_origin()
  236. /*resets the coordinates for the new block*/
  237. {
  238.   block_x = MAXX-3;
  239.   block_y = MAXY-1;
  240. }
  241. /*----------------------------------------------------------------------*/
  242.  
  243. void
  244. remove_block()
  245. /*removes block from frequency table */
  246. {
  247.   num_blk[current_block]--;
  248.   if (current_block >= ONEWAY) oneway--;
  249. }
  250.  
  251. /*----------------------------------------------------------------------*/
  252.  
  253. void
  254. place_objects(levelnum)
  255. int levelnum;
  256. { int i;
  257.   for (i=0 ; i <MAXY; i++)
  258.     { if (obmaps[levelnum][i] !=0 )
  259.     {
  260.       pipe_board[obmaps[levelnum][i]][i] = 
  261.         ((int)random() %((OBSFIN-OBSRT)+1)) + OBSRT;
  262.     }
  263.     }
  264. }
  265. /*----------------------------------------------------------------------*/
  266.  
  267. void
  268. increment_sequence()
  269. {
  270.   int y,blk_num;
  271.    blk_num = last_new_block;
  272.    pipe_board[MAXX-3][MAXY-1] = pipe_board[MAXX-2][MAXY-1];
  273.  
  274.     for (y=MAXY-1; y >0 ; y--)
  275.       pipe_board[MAXX-2][y] = pipe_board[MAXX-2][y-1];
  276.  
  277.   while (blk_num == last_new_block) {
  278.     blk_num = (int)random() % (MaxBlockNo-1);  /*don't count empty block*/
  279.     blk_num = blk_num+1;
  280.     if ((blk_num >= ONEWAY) && (oneway >=MAXONEWAYS))
  281.       blk_num = last_new_block;
  282.     else {
  283.       if (num_blk[blk_num] > 1) blk_num = last_new_block;
  284.       else if (blk_num != last_new_block) num_blk[blk_num]++;
  285.       if (blk_num >= ONEWAY && (blk_num != last_new_block)) oneway++;
  286.     }
  287.   }
  288.   pipe_board[MAXX-2][0] = blk_num;
  289.   last_new_block = blk_num;
  290.  
  291.   redisplay_sequence();  
  292.   current_block = pipe_board[MAXX-3][MAXY-1];
  293.  
  294. }
  295. /*----------------------------------------------------------------------*/
  296.   
  297. void
  298. initialise_sequence()
  299. {
  300.     int  y,blk_num=0,last_blk_num =0;
  301.     oneway = 1;
  302.     for (y=1 ; y<= MaxBlockNo; y++)
  303.       num_blk[y] = 0;   /*only 2 of each block allowed any any time */
  304.  
  305.     blk_num = (int)random() % (MaxBlockNo-1);  /*don't count empty block*/
  306.     blk_num = last_blk_num = blk_num+1;
  307.     pipe_board[MAXX-3][MAXY-1] = blk_num;
  308.     num_blk[blk_num]++;
  309.         
  310.     for (y =(MAXY-1) ; y >= 0 ; y--)   /*set up block sequence */
  311.       { 
  312.     while (blk_num == last_blk_num) {
  313.       blk_num = (int)random() % (MaxBlockNo-1);  /*don't count empty block*/
  314.       blk_num = blk_num+1;
  315.       if ((blk_num >= ONEWAY) && (oneway>= MAXONEWAYS)) 
  316.         blk_num = last_blk_num;
  317.       else {
  318.         if (num_blk[blk_num] > 1) blk_num = last_blk_num;
  319.         else if (blk_num != last_blk_num) num_blk[blk_num]++;
  320.         if (blk_num >= ONEWAY && (blk_num != last_blk_num)) oneway++;
  321.       }
  322.     }
  323.         
  324.         last_blk_num = blk_num;
  325.         pipe_board[MAXX-2][y] = blk_num;
  326.       }
  327.     current_block = pipe_board[MAXX-3][MAXY-1];
  328.     last_new_block  = pipe_board[MAXX-2][0];
  329.   }
  330.  
  331. /*----------------------------------------------------------------------*/
  332. void
  333. level_over(data,id)
  334. caddr_t data;
  335. XtIntervalId *id;
  336. {    /* find any unconnected blocks  -10 for each one! */
  337.   int x,y; 
  338.  for(y=0;y<MAXY;y++)
  339.   {
  340.     for(x=0;x<MAXX-3;x++)
  341.       { if ((pipe_board[x][y] >0 ) && (pipe_board[x][y] < TOTALBLOCKS))
  342.       {
  343.         new_score(-10);
  344.         pipe_board[x][y] = EMPTY;
  345.         redraw_block(x,y);
  346.       }
  347.       }
  348.   }
  349.   if (flow_blocks >= blocksrequired[level-1])
  350.     {
  351.       show_level_over_popup();
  352.     }
  353.   else
  354.     {
  355.       show_game_over_popup();
  356.       current_callback = XtAddTimeOut(3000,game_over,NULL);
  357.     }
  358. }
  359. /*----------------------------------------------------------------------*/
  360. void
  361. game_over(data,id)
  362. caddr_t data;
  363. XtIntervalId *id;
  364. {
  365.   game_active =0;
  366.   game_over_popdown();
  367.   nomore_popdown();
  368.   new_score(bonus);
  369.   check_score(score);
  370.   reset_bonus();
  371. }
  372. /*----------------------------------------------------------------------*/
  373. void
  374. start_new_level()
  375. {
  376.   if (level > 0)                  /* add in the bonus from previous level */
  377.     {
  378.       new_score(bonus);
  379.       reset_bonus();
  380.     }
  381.   new_level();
  382. }
  383. /*----------------------------------------------------------------------*/
  384. void
  385. new_level()
  386. {
  387.   int x,y,tmp;
  388.  
  389.   if (level >= MAXLEVELS){
  390.     game_active =0 ;
  391.     show_nomore_popup();
  392.     current_callback = XtAddTimeOut(3000,game_over,NULL);
  393.   }
  394.   else 
  395.     {
  396.       update_level(level);
  397.  
  398.       for_each                            /* clean out the array */
  399.     {
  400.       pipe_board[x][y] = EMPTY;
  401.     }
  402.       
  403.       for (y=0 ; y < MAXY-1 ; y++)         /*draw 2 vertical bars*/
  404.     {
  405.       pipe_board[MAXX-3][y] = BAR;
  406.       pipe_board[MAXX-1][y] = BAR;
  407.     }
  408.       pipe_board[MAXX-1][MAXY-1] = BAR;
  409.       pipe_board[MAXX-3][MAXY-2] = ARROW;
  410.       pipe_board[MAXX-3][1]      = SHOWFLOW+3;
  411.  
  412.       for (y=2 ; y < 5 ; y ++)
  413.     pipe_board[MAXX-3][y] = SHOWFLOW;
  414.       if (level >= onewaytime)
  415.     MaxBlockNo = TOTALBLOCKS;
  416.       else
  417.     MaxBlockNo = NUMBLOCKS;
  418.  
  419.       initialise_sequence();
  420.       place_objects(level);
  421.       do
  422.     {
  423.       flow_x = ((int)random()%(MAXX-6)) +2;   /* assign start to new space */
  424.       flow_y = ((int)random()%(MAXY-4)) +1;
  425.     }
  426.       while ((pipe_board[flow_x][flow_y] != EMPTY) ||
  427.          (pipe_board[flow_x+1][flow_y] != EMPTY) ||
  428.          (pipe_board[flow_x+1][flow_y+1] != EMPTY) ||
  429.          (pipe_board[flow_x+1][flow_y-1] != EMPTY));
  430.       
  431.       pipe_board[flow_x][flow_y] = START;
  432.       
  433.       remaining_blocks=blocksrequired[level];
  434.       update_remain(remaining_blocks);
  435.       flow_dir = FRIGHT;  /* must flow right out of the start block */
  436.       flow_blocks = 0;
  437.       flow_time = flowrate[level];
  438.       flow_time_start = flowstart[level]/ 6 ;
  439.  
  440.       blkstarttime =0;
  441.       blktime=3;
  442.       blkrstart=0;
  443.       blkfull = STARTFULL;
  444.  
  445.       if (current_callback != NULL)
  446.     XtRemoveTimeOut(current_callback);
  447.       current_callback = XtAddTimeOut(flow_time_start,show_when_flow,NULL);
  448.       
  449.       reset_block_origin();
  450.       display_level();
  451.       
  452.       level++;
  453.       buttons_disabled=0;
  454.     }
  455. }
  456. /*----------------------------------------------------------------------*/
  457.  
  458. void
  459. speed_up_flow()
  460. { int i;
  461.  if (current_callback != NULL)
  462.    XtRemoveTimeOut(current_callback);
  463.  flow_time = FASTFLOW;
  464.  current_callback= XtAddTimeOut(flow_time,draw_flow,NULL);
  465.  for (i=2 ; i <5 ; i++)
  466.    {      /* make sure flow start meter full */
  467.      pipe_board[MAXX-3][i] = SHOWFLOW+2 ;
  468.      redraw_block(MAXX-3,i);
  469.    }
  470.  
  471. }
  472. /*----------------------------------------------------------------------*/
  473. void
  474. show_when_flow(data,id)
  475. caddr_t data;
  476. XtIntervalId *id;
  477. { int start_flowing=0;
  478.  
  479.   blkstarttime++;
  480.  
  481.   switch (blkstarttime) {
  482.     case 1: {
  483.       pipe_board[MAXX-3][4] = SHOWFLOW+1;
  484.       redraw_block(MAXX-3,4);
  485.       break;
  486.     }
  487.     case 2: {
  488.       pipe_board[MAXX-3][4] = SHOWFLOW+2;
  489.       redraw_block(MAXX-3,4);
  490.       break;
  491.     }
  492.     case 3: {
  493.       pipe_board[MAXX-3][3] = SHOWFLOW+1;
  494.       redraw_block(MAXX-3,3);
  495.       break;
  496.     }
  497.     case 4: {
  498.       pipe_board[MAXX-3][3] = SHOWFLOW+2;
  499.       redraw_block(MAXX-3,3);
  500.       break;
  501.     }
  502.     case 5: {
  503.       pipe_board[MAXX-3][2] = SHOWFLOW+1;
  504.       redraw_block(MAXX-3,2);
  505.       break;
  506.     }
  507.     case 6: {
  508.       pipe_board[MAXX-3][2] = SHOWFLOW+2;
  509.       redraw_block(MAXX-3,2);
  510.       start_flowing =1;
  511.  
  512.       break;
  513.     }
  514.     default: {}
  515.     }
  516.    if (start_flowing)
  517.      {
  518.       if (current_callback != NULL)
  519.     XtRemoveTimeOut(current_callback);
  520.       current_callback = XtAddTimeOut(flow_time_start,draw_flow,NULL);
  521.     }
  522.   else
  523.     {
  524.       if (current_callback != NULL)
  525.     XtRemoveTimeOut(current_callback);
  526.       current_callback = XtAddTimeOut(flow_time_start,show_when_flow,NULL);
  527.     }
  528. }
  529.     
  530. /*----------------------------------------------------------------------*/
  531. void
  532. draw_flow(data,id)
  533. caddr_t data;
  534. XtIntervalId *id;
  535. {
  536.   current_callback = NULL;
  537.   if (blktime < 2)
  538.     {
  539.       pipe_board[flow_x][flow_y] = blkrstart++;
  540.       current_callback= XtAddTimeOut(flow_time,draw_flow,NULL);
  541.       redraw_block(flow_x,flow_y);
  542.       blktime++;
  543.     }
  544.   else
  545.     {
  546.       pipe_board[flow_x][flow_y] = blkfull;
  547.       redraw_block(flow_x,flow_y);
  548.       increment_flow();
  549.     } 
  550. }
  551.   
  552. /*----------------------------------------------------------------------*/
  553. void
  554. increment_flow()
  555.  
  556. {
  557.   int new_dir,i,failed=0;
  558.   caddr_t data;  /*dummy variables*/
  559.   XtIntervalId *id;
  560.       switch (flow_dir) {
  561.       case FLEFT: { 
  562.     flow_x--;
  563.     break;
  564.       }
  565.       case FRIGHT: { 
  566.     flow_x++;
  567.     break;
  568.       }
  569.       case FDOWN: { 
  570.     flow_y++;
  571.     break;
  572.       }
  573.       case FUP: { 
  574.     flow_y--;
  575.     break;
  576.       }
  577.       }
  578.  
  579.       if ((!(INYRANGE(flow_y) && INXRANGE(flow_x))) ||
  580.       (pipe_board[flow_x][flow_y] >= FILLBLKSTART)) failed=TRUE;
  581.       else if (!(failed = ((new_dir= flow[pipe_board[flow_x][flow_y]][flow_dir^3]) == BLOCKED)))
  582.        flow_blocks++;
  583.  
  584.  
  585.       if (failed) {
  586.     buttons_disabled = 1;
  587.     if (current_callback != NULL)
  588.       XtRemoveTimeOut(current_callback);
  589.     current_callback = XtAddTimeOut(3000,level_over,NULL);
  590.       }
  591.       else
  592.     {
  593.       block_replace(flow_dir^3);
  594.           if (remaining_blocks >0)
  595.         update_remain(--remaining_blocks);
  596.       flow_dir = new_dir;
  597.       draw_flow(data,id);
  598.     }
  599. }    
  600.  
  601. void
  602. block_replace(flw_dir)
  603. int flw_dir;
  604.  
  605. {
  606.    int curr_block,first,setalready=0,blk_score=0,blk_bonus=0;
  607.    curr_block = pipe_board[flow_x][flow_y];
  608.    blk_score=10;  /* 10 points for connectin a pipe */
  609.    switch (curr_block) {
  610.    case 1:{
  611.      if (flw_dir == FLEFT)
  612.         first = 1;
  613.      else first = 0;
  614.      break;
  615.    }
  616.    case 2:{
  617.      if (flw_dir == FUP)
  618.         first = 1;
  619.      else first = 0;
  620.      break;
  621.    }
  622.    case 3:{
  623.      if (flw_dir == FRIGHT)
  624.         first = 1;
  625.      else first = 0;
  626.      break;
  627.    }
  628.    case 4:{
  629.      if (flw_dir == FLEFT)
  630.         first = 1;
  631.      else first = 0;
  632.      break;
  633.    }
  634.    case 5:{
  635.      if (flw_dir == FRIGHT)
  636.         first = 1;
  637.      else first = 0;
  638.      break;
  639.    }
  640.    case 6:{
  641.      if (flw_dir == FLEFT)
  642.         first = 1;
  643.      else first = 0;
  644.      break;
  645.    }
  646.    case 7:{
  647.      if (flw_dir == FLEFT){
  648.        blkrstart = FILLBLKSTART + (curr_block-1)*5;
  649.        blkfull   = HFULL;}
  650.  
  651.      else if (flw_dir==FRIGHT) {
  652.        blkrstart = FILLBLKSTART + (curr_block-1)*5 +3;
  653.        blkfull   = HFULL; }  
  654.  
  655.      else if (flw_dir==FUP){
  656.        blkrstart = FILLBLKSTART + (curr_block-1)*5 +5;
  657.        blkfull   = VFULL;}
  658.  
  659.      else if (flw_dir==FDOWN) {
  660.        blkrstart = FILLBLKSTART + (curr_block-1)*5 +3+5;
  661.        blkfull   = VFULL; }  
  662.      setalready = 1;
  663.  
  664.      break;
  665.    }
  666.    case ONEWAY:
  667.    case (ONEWAY+1):{
  668.      blkrstart = FILLBLKSTART + (curr_block-ONEWAY)*5;
  669.      blkfull   = FILLBLKSTART + (curr_block-ONEWAY)*5 + 2;
  670.      setalready =1;
  671.      blk_bonus = 10;
  672.      break;
  673.    }
  674.    case (ONEWAY+2):
  675.    case (ONEWAY+3):
  676.    case (ONEWAY+4):
  677.    case (ONEWAY+5):{
  678.      blkrstart = FILLBLKSTART + (curr_block-ONEWAY)*5 +3;
  679.      blkfull   = FILLBLKSTART + (curr_block-ONEWAY)*5 + 2;
  680.      setalready =1;
  681.      blk_bonus = 10;
  682.      break;
  683.    }
  684.    case HFULL:{
  685.      if (flw_dir == FUP)
  686.      blkrstart = FILLBLKSTART + (8-1)*5 +5;
  687.      else 
  688.        blkrstart = FILLBLKSTART + (8-1)*5 +3+5;
  689.        blkfull = FILLBLKSTART + (8-1)*5 +2+5;
  690.      setalready = 1;
  691.      blk_bonus = 40;  /*40 points for creating a loop */
  692.      break;
  693.    }
  694.    case VFULL:{
  695.      if (flw_dir == FLEFT)
  696.      blkrstart = FILLBLKSTART + (9-1)*5 +5;
  697.      else 
  698.        blkrstart = FILLBLKSTART + (9-1)*5 +3+5;
  699.        blkfull = FILLBLKSTART + (9-1)*5 +2+5;
  700.      setalready = 1;
  701.      blk_bonus = 40;  /*40 points for creating a loop */
  702.      break;
  703.    }
  704.    default:
  705.      break;
  706.    }
  707.  
  708.    if (!setalready)
  709.      {
  710.        if (first)
  711.      blkrstart = FILLBLKSTART + (curr_block-1)*5;
  712.        else
  713.      blkrstart = FILLBLKSTART + (curr_block-1)*5 +3;
  714.        blkfull = FILLBLKSTART + (curr_block-1)*5 +2;
  715.      }
  716.    blktime=0;
  717.    new_score(blk_score);
  718.    new_bonus(blk_bonus);
  719. }  
  720. /*----------------------------------------------------------------------*/
  721. int
  722. can_go(x,y)
  723.   int x,y;
  724. {
  725.  
  726.   if( INYRANGE(y) ) 
  727.     if( INXRANGE(x) ) {
  728.       if (pipe_board[x][y] == BAR)    return 0;
  729.     }
  730.  
  731.   if( !INXRANGE(x) )  return 0;
  732.   if( !INYRANGE(y) )  return 0;
  733.  
  734.   return 1;
  735. }
  736. /*----------------------------------------------------------------------*/
  737. int
  738. can_place(x,y)
  739.   int x,y;
  740. {
  741.  
  742.   if( INYRANGE(y) ) 
  743.     if( INXRANGE(x) ) {
  744.       if (pipe_board[x][y] >= FILLBLKSTART) return 0;
  745.     }
  746.  
  747.   if( !INXRANGE(x) )  return 0;
  748.   if( !INYRANGE(y) )  return 0;
  749.  
  750.   return 1;
  751. }
  752.  
  753.  
  754. /*KLUDGE!!!*/
  755. XmuCvtStringToPixmap(a, b, c, d, e, f)
  756.   int    a, b, c, d, e, f;
  757. {
  758.     XmuCvtStringToBitmap(a, b, c, d, e, f);
  759. }
  760.  
  761.